﻿using Microsoft.Xaml.Behaviors;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

namespace Common;

/// <summary>
/// 为什么选择FrameworkElement 
/// 可选的有ItemsControl 里有一个Items
/// Panel有Children，无论继承哪一个都不那么灵活
/// </summary>
public class SelectItemBehavior : Behavior<FrameworkElement>
{


    public object SelectItem
    {
        get { return (object)GetValue(SelectItemProperty); }
        set { SetValue(SelectItemProperty, value); }
    }

    public static readonly DependencyProperty SelectItemProperty =
        DependencyProperty.Register(nameof(SelectItem), typeof(object), typeof(SelectItemBehavior), new PropertyMetadata(null, CallBack));

    /// <summary>
    /// 修改其他选项，虽然在一个组内会自动修改
    /// </summary>
    /// <param name="d"></param>
    /// <param name="e"></param>
    private static void CallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        //拿到其自身
        var behavior = Interaction.GetBehaviors(d).OfType<SelectItemBehavior>().FirstOrDefault();
        if (behavior is null) { return; }
        foreach (var item in behavior.Children)
        {
            item.IsChecked = item.Tag.Equals(e.NewValue);
            //item.IsChecked = item.Tag.Equals(behavior.SelectItem);
        }
    }

    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.Loaded += AssociatedObject_Loaded;


    }

    /// <summary>
    /// 加载后再注册，否则事件注册不上(因为Behavior的代码写在Radio前面，不能控制代码的先后所以使用Loaded事件)
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
    {
        foreach (var item in Children)
        {
            item.Checked += Item_Checked;
            item.IsChecked = item.Tag.Equals(SelectItem);
        }
    }

    private void Item_Checked(object sender, RoutedEventArgs e)
    {
        var radio = (RadioButton)sender;
        //【TODO】
        SelectItem = radio.Tag;
        //【TODO】
        //BindingOperations.GetBindingExpression(this, SelectItemProperty)?.UpdateSource();
        var b = BindingOperations.GetBindingExpression(this, SelectItemProperty);
        if (b != null)
        { 
            b.UpdateSource();
        }
    }

    private IEnumerable<RadioButton> Children
    {
        get
        {
            if (AssociatedObject is Panel panel)
                return panel.Children.OfType<RadioButton>();
            else if (AssociatedObject is ItemsControl items)
                return items.Items.OfType<RadioButton>();
            return Enumerable.Empty<RadioButton>();
            //throw new NotImplementedException();
        }
    }
}
